#ifndef Mkeyin3_h
#define Mkeyin3_h
#include "Arduino.h"
class Mkeyin3 {
private:
byte BK1;
byte BK2;
byte BK3;
byte BK4;
byte BK5;
byte BK6;
byte BK7;
byte BK8;
byte BK9;
byte BK10;
byte BK11;
byte BK12;
byte BK13;
byte BK14;
byte BK15;
byte BK16;
const uint16_t dataWidth;
uint8_t pulseWidth;
uint16_t lastState;
uint16_t currentState;
public:	
	Mkeyin3() : dataWidth(16), pulseWidth(5), lastState(0), currentState(0) {}
	// setup all pins
	void begin() {
		pinMode(BK1=10, INPUT_PULLUP);
		pinMode(BK2=11, INPUT_PULLUP);
		pinMode(BK3=12, INPUT_PULLUP);
        pinMode(BK4=13, INPUT_PULLUP);
        pinMode(BK5=14, INPUT_PULLUP);
        pinMode(BK6=15, INPUT_PULLUP);
        pinMode(BK7=16, INPUT_PULLUP);
        pinMode(BK8=21, INPUT_PULLUP);
        pinMode(BK9=17, INPUT_PULLUP);
        pinMode(BK10=33, INPUT_PULLUP);
        pinMode(BK11=34, INPUT_PULLUP);
        pinMode(BK12=35, INPUT_PULLUP);
        pinMode(BK13=45, INPUT_PULLUP);
        pinMode(BK14=18, INPUT_PULLUP);
        pinMode(BK15=7, INPUT_PULLUP);
        pinMode(BK16=6, INPUT_PULLUP);
	}
	
	inline uint8_t getPulseWidth() { return pulseWidth; }
	inline void setPulseWidth(uint8_t value) { pulseWidth = value; }
	inline uint16_t getDataWidth() { return dataWidth; }
	// whether some value has changed
	inline boolean hasChanged() { return lastState != currentState; }
	// whether the value with index 'id' has changed
	inline boolean hasChanged(int id) { return state(id) != last(id); }
	// returns the state from the last frame
	inline uint16_t getLast() { return lastState; }
	// returns the current state
	inline uint16_t getCurrent() { return currentState; }
	// whether button 'id' is pressed or not
	inline boolean state(int id) { return bitRead(currentState, id); }
	// whether button 'id' was pressed in the last frame
	inline boolean last(int id) { return bitRead(lastState, id); }
	// whether button 'id' is now pressed, but wasn't pressed in the last frame
	inline boolean pressed(int id) { return !last(id) && state(id); }
	// whether button 'id' is now released, but was pressed in the last frame
	inline boolean released(int id) { return last(id) && !state(id); }
	
	// read in data from shift register and return the new value
	uint16_t read() {
	const int Button_data[]={21,16,15,14,13,12,11,10,7,6,18,45,35,34,33,17};//PIN
		lastState = currentState;
		uint16_t result = 0;
		for(int i = 0; i < dataWidth; i++) {
			uint16_t value = digitalRead(Button_data[i]);
			result |= (value << ((dataWidth-1) - i));
		}
		currentState = result;
		return result;
	}
	
	// same as read, but it returns whether something has changed or not
	boolean update() {
		return read() != lastState;
	}
};

#endif